package app.utils;

import com.google.common.base.Strings;
import com.ifonly.logger.Logger;
import com.ifonly.utils.ArrayUtils;
import com.ifonly.utils.IOUtils;
import net.coobird.thumbnailator.Thumbnails;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;

/**
 * @author ifonly
 * @version 1.0 2016-02-19 16:22
 * @since JDK 1.6
 */
public class FileUtils {
    private static Logger LOGGER = Logger.getLogger(FileUtils.class);

    /**
     * 计算文件的 MD5 值
     *
     * @param file 需要计算的文件
     * @return MD5值
     */
    public static String md5(File file) {
        String value = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(byteBuffer);
            BigInteger bi = new BigInteger(1, md5.digest());
            value = bi.toString(16);
        } catch (Exception e) {
            LOGGER.error("MD5 ERROR", e);
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    //ignore
                }
            }
        }
        return value;
    }

    /**
     * 获取文件的后缀名 不带 "."
     *
     * @param fileName 文件名
     * @return 后缀名
     */
    public static String getSuffix(String fileName) {
        if (fileName.contains(".")) {
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        }
        return "";
    }

    /**
     * 文件复制
     *
     * @param src 源文件
     * @param desc 目标文件
     */
    public static void copy(File src, File desc) {
        if (!src.exists()) {
            throw new IllegalArgumentException("");
        }

        if (src.isDirectory()) { // 文件夹, 将 src 下所有文件复制到 desc 下
            if (!desc.exists()) {
                if (!desc.mkdirs()) {
                    throw new RuntimeException("mkdirs: " + desc + "failed");
                }
            }
            File[] files = src.listFiles();
            if (files != null) {
                for (File file : files) {
                    System.out.println(file.getAbsoluteFile());
                    copy(file, new File(desc, file.getName()));
                }
            }
        } else {
            FileChannel in = null;
            FileChannel out = null;
            FileInputStream inStream = null;
            FileOutputStream outStream = null;

            if (!desc.exists()) {
                try {
                    if (!desc.getParentFile().exists() && !desc.getParentFile().mkdirs()) {
                        throw new RuntimeException("mkdirs: " + desc.getParentFile() + " failed");
                    }
                    if (!desc.createNewFile()) {
                        throw new RuntimeException("createNewFile: " + desc + " failed");
                    }
                } catch (IOException e) {
                    throw new RuntimeException("createNewFile: " + desc + " failed");
                }
            } else {
                if (desc.isDirectory()) {
                    desc = new File(desc, src.getName());
                }
            }
            try {
                inStream = new FileInputStream(src);
                outStream = new FileOutputStream(desc);
                in = inStream.getChannel();
                out = outStream.getChannel();
                in.transferTo(0, in.size(), out);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.close(inStream);
                IOUtils.close(in);
                IOUtils.close(outStream);
                IOUtils.close(out);
            }
        }
    }

    /**
     * 生成缩略图
     *
     * @param image 原图
     * @param sizes 生成之后的大小
     */
    public static void thumb(File image, int[][] sizes) {
        File parent = image.getParentFile();
        String fileName = image.getName();
        String suffix = getSuffix(fileName);
        suffix = Strings.isNullOrEmpty(suffix) ? "" : "." + suffix;
        String nameWithSuffix = nameWithSuffix(fileName);
        for (int[] size : sizes) {
            try {
                String outFileName = nameWithSuffix + "_" + size[0] + "x" + size[1] + suffix;
                Thumbnails.of(image).size(size[0], size[1]).toFile(new File(parent, outFileName));
            } catch (IOException e) {
                LOGGER.error("thumb file error", e);
            }
        }
    }

    /**
     * 获取不包含后缀的文件名
     *
     * @param name 文件名
     * @return 不包含后缀的文件名
     */
    public static String nameWithSuffix(String name) {
        String result = name;
        if (name.lastIndexOf('.') > -1) {
            result = name.substring(0, name.lastIndexOf('.'));
        }
        return result;
    }

    /**
     * 删除文件 如果是目录,则递归删除该目录下所有的文件然后删除当前目录
     *
     * @param file File
     */
    public static void delete(File file) {
        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (!ArrayUtils.isNullOrEmpty(children)) {
                for (File f : children) {
                    delete(f);
                }
            }
        }

        if (file.exists() && !file.delete()){
            LOGGER.error("delete file[" + file + "] failed");
            throw new RuntimeException("delete file[" + file + "] failed");
        }
    }

    /**
     * 删除图片文件, 同时删除生成的缩略图
     *
     * @param image 原图
     * @param sizes 生成之后的大小
     */
    public static void delete(File image, int[][] sizes) {
        File parent = image.getParentFile();
        String fileName = image.getName();
        String suffix = getSuffix(fileName);
        suffix = Strings.isNullOrEmpty(suffix) ? "" : "." + suffix;
        String nameWithSuffix = nameWithSuffix(fileName);

        for (int[] size : sizes) {
            String outFileName = nameWithSuffix + "_" + size[0] + "x" + size[1] + suffix;
            delete(new File(parent, outFileName));
        }
        delete(image);
    }

    public static void main(String[] args) {
        //System.out.println(getSuffix("a."));
        //copy(new File("/Users/jerry/workspace/myProjs/ifonly/src/test/java/aop/Hello.java"), new File("/Users/jerry/workspace/myProjs/ifonly/target"));
//        thumb(new File("/Users/jerry/workspace/myProjs/ifonly/target/ifonly/uploads/dish_cover/20160219/1f87976669594600a2f175a8639f9b44.png"), new int[][] {
//                {50, 50},
//                {100, 100},
//                {150, 150},
//                {200, 200},
//        });

        delete(new File("/Users/jerry/workspace/myProjs/ifonly/target/ifonly/uploads/dish_cover"));
    }

}
